home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Online / SpeakFreely / src / lpc10 / analys.c next >
C/C++ Source or Header  |  2000-05-18  |  7KB  |  243 lines

  1.  
  2. /*******************************************************************
  3. *
  4. *    ANALYS Version 50
  5. *
  6. *******************************************************************/
  7. #include <stdlib.h>
  8. #include "lpcdefs.h"
  9. #include "config.ch"
  10.  
  11. /*  Constants
  12. *    NF =     Number of frames
  13. *    AF =     Frame in which analysis is done
  14. *    OSLEN =  Length of the onset buffer
  15. *    LTAU =   Number of pitch lags
  16. *    SBUFL, SBUFH =   Start and end index of speech buffers
  17. *    LBUFL, LBUFH =   Start and end index of LPF speech buffer
  18. *    MINWIN, MAXWIN = Min and Max length of voicing (and analysis) windows
  19. *    PWLEN, PWINH, PWINL = Length, upper and lower limits of pitch window
  20. *    DVWINL, DVWINH = Default lower and upper limits of voicing window
  21. */
  22.  
  23.  
  24. #define LPFILT_DELAY 15
  25. #define NUM_VF 9
  26.  
  27. extern int tau[LTAU];
  28. extern float lparray[LBUFH-LBUFL+1], ivarray[PWINH-PWINL+1];
  29. extern float pearray[SBUFH-SBUFL+1], inarray[SBUFH-SBUFL+1];
  30. extern float *inbuf, *pebuf, *lpbuf, *ivbuf;
  31. extern int vwin[2][AF], awin[2][AF], voibuf[2][AF+1];
  32. extern float rmsbuf[AF], amdf[LTAU], psi[MAXORD], rcbuf[MAXORD][AF];
  33. extern float phi[MAXORD][MAXORD];
  34.  
  35. static float zpre[2]={0.0, 0.0};
  36.  
  37. analys( speech, voice, pitch, rms, rc )
  38. float speech[];  
  39. float *rms, rc[];
  40. int voice[2], *pitch;
  41. {
  42. /*  Data Buffers
  43. *    INBUF    Raw speech (with DC bias removed each frame)
  44. *    PEBUF    Preemphasized speech
  45. *    LPBUF    Low pass speech buffer
  46. *    IVBUF    Inverse filtered speech
  47. *    OSBUF    Indexes of onsets in speech buffers
  48. *    VWIN    Voicing window indices
  49. *    AWIN    Analysis window indices
  50. *    EWIN    Energy window indices
  51. *    VOIBUF    Voicing decisions on windows in VWIN
  52. *    RMSBUF    RMS energy
  53. *    RCBUF    Reflection Coefficients
  54. *
  55. *  Pitch is handled separately from the above parameters.
  56. *  The following variables deal with pitch:
  57. *    MIDX    Encoded initial pitch estimate for analysis frame
  58. *    IPITCH    Initial pitch computed for frame AF (decoded from MIDX)
  59. *    PITCH    The encoded pitch value (index into TAU) for the present
  60. *        frame (delayed and smoothed by Dyptrack)
  61. */
  62.  
  63. /*    REAL INBUF(SBUFL:SBUFH), PEBUF(SBUFL:SBUFH)
  64.     REAL LPBUF(LBUFL:LBUFH), IVBUF(PWINL:PWINH)    */
  65.  
  66.  
  67. float abuf[MAXWIN], temp;
  68. static float bias=0.;
  69. static int osptr=1;
  70. static int obound[AF];
  71. static int ewin[2][AF];
  72.  
  73. int i, j, lanal;
  74. int ipitch, minptr, maxptr, mintau, midx;
  75. float ivrc[2];
  76.  
  77. static int osbuf[OSLEN], first=1;
  78.  
  79. #ifdef NN_VOICE
  80. int vstart;
  81. #else
  82. int half;
  83. #endif
  84.  
  85. if (first)    {
  86.     first = 0;
  87.     for(i=0;i<OSLEN;i++)
  88.       osbuf[i] = 0;
  89.     for(i=0;i<AF;i++);
  90.       obound[i] = 0;
  91. }
  92.  
  93. speech--;
  94.  
  95. /*   Calculations are done on future frame due to requirements
  96. *   of the pitch tracker.  Delay RMS and RC's 2 frames to give
  97. *   current frame parameters on return.
  98. *   Update all buffers
  99. */
  100.  
  101. for (i = SBUFL;i<=SBUFH-LFRAME;i++) {
  102.     inbuf[i] = inbuf[LFRAME+i];
  103.     pebuf[i] = pebuf[LFRAME+i];
  104. }
  105.  
  106. for( i = PWINL; i<=PWINH-LFRAME; i++) {
  107.        ivbuf[i] = ivbuf[LFRAME+i];
  108. }
  109. for( i = LBUFL;i<=LBUFH-LFRAME;i++) {
  110.        lpbuf[i] = lpbuf[LFRAME+i];
  111. }
  112.  
  113.  
  114. /* loop below adjusted for C indexing */
  115. j=1;
  116. for( i = 1;i<=osptr-1;i++) {
  117.     if (osbuf[i-1] > LFRAME) {
  118.         osbuf[j-1]=osbuf[i-1]-LFRAME;
  119.         j++;
  120.   }
  121. }
  122. osptr=j;
  123.  
  124. voibuf[0][0] = voibuf[0][1];
  125. voibuf[1][0] = voibuf[1][1];
  126. for( i = 0;i<AF-1;i++) {
  127.     vwin[0][i] = vwin[0][i+1] - LFRAME;
  128.     vwin[1][i] = vwin[1][i+1] - LFRAME;
  129.     awin[0][i] = awin[0][i+1] - LFRAME;
  130.     awin[1][i] = awin[1][i+1] - LFRAME;
  131.     ewin[0][i] = ewin[0][i+1] - LFRAME;
  132.     ewin[1][i] = ewin[1][i+1] - LFRAME;
  133.     obound[i] = obound[i+1];
  134.     voibuf[0][i+1] = voibuf[0][i+2];
  135.     voibuf[1][i+1] = voibuf[1][i+2];
  136.     rmsbuf[i] = rmsbuf[i+1];
  137.     for( j = 0;j<ORDER;j++) {
  138.         rcbuf[j][i] = rcbuf[j][i+1];
  139.     }
  140. }
  141.  
  142. /*   Copy input speech, scale to sign+12 bit integers
  143. *   Remove long term DC bias.  (This code can be removed
  144. *   if adequate high pass filtering and reliable A/D
  145. *   conversion is available)
  146. */
  147.  
  148.  
  149. temp = 0;
  150. for( i = 1;i<=LFRAME;i++){
  151.     inbuf[SBUFH-LFRAME+i] = *(speech+i)*4096. - bias;
  152.     temp += inbuf[SBUFH-LFRAME+i];
  153. }
  154. if( temp > LFRAME ) bias++;
  155. if( temp < -LFRAME ) bias--;
  156.  
  157. /*   Place Voicing Window  */
  158.  
  159. i = SBUFH + 1 - LFRAME;
  160. preemp( &inbuf[i-1], &pebuf[i-1], LFRAME, 0.4, zpre );
  161.  
  162. onset( pebuf, osbuf-1, &osptr);
  163.  
  164. placev(osbuf, osptr, &obound[AF-1],vwin);
  165.  
  166. /*      The Pitch Extraction algorithm estimates the pitch for a frame
  167. *   of speech by locating the minimum of the average magnitude difference
  168. *   function (AMDF).  The AMDF operates on low-pass, inverse filtered
  169. *   speech.  (The low-pass filter is an 800 Hz, 19 tap, equiripple, FIR
  170. *   filter and the inverse filter is a 2nd-order LPC filter.)  The pitch
  171. *   estimate is later refined by dynamic programming (DYPTRK).    However,
  172. *   since some of DYPTRK's parameters are a function of the voicing
  173. *   decisions, a voicing decision must precede the final pitch estimation.
  174. *   See subroutines LPFILT, IVFILT, and TBDM. 
  175. */
  176.  
  177. lpfilt31(&inbuf[LBUFH-1-PWLEN-1], &lpbuf[LBUFH+1-PWLEN-1]);
  178.  
  179. ivfilt( &lpbuf[PWINL-1], &ivbuf[PWINL-1], ivrc-1 );  /*C-shifted*/
  180.  
  181. tbdm( &ivbuf[PWINL-1], tau-1, amdf-1, &minptr, &maxptr, &mintau ); /*C-shifted*/
  182.  
  183. /*      Voicing decisions are made for each half frame of input speech.
  184. *   An initial voicing classification is made for each half of the
  185. *   analysis frame, and the voicing decisions for the present frame
  186. *   are finalized.  See subroutine VOICIN.
  187. *     The voicing detector (VOICIN) classifies the input signal as
  188. *   unvoiced (including silence) or voiced using the AMDF windowed
  189. *   maximum-to-minimum ratio, the zero crossing rate, energy measures,
  190. *   reflection coefficients, and prediction gains. 
  191. *     The pitch and voicing rules apply smoothing and isolated
  192. *   corrections to the pitch and voicing estimates and, in the process,
  193. *   introduce two frames of delay into the corrected pitch estimates and 
  194. *   voicing decisions.
  195. */
  196.  
  197. #ifndef NN_VOICE
  198. for (half = 1;half<=2;half++) {
  199.   voicin( vwin, inbuf, lpbuf, half, amdf[minptr-1], amdf[maxptr-1], mintau, ivrc-1, obound-1, voibuf);
  200. }
  201.  
  202. #else
  203.  
  204. vstart = PWINL + (PWLEN>>1) - (LFRAME>>1);
  205. voicing(inbuf, lpbuf+LPFILT_DELAY, vstart, vstart+LFRAME-1, mintau, &voibuf[0][3], &voibuf[1][3]);
  206. #endif
  207. /*   Find the minimum cost pitch decision over several frames
  208. *   given the current voicing decision and the AMDF array
  209. */
  210.  
  211. dyptrk(amdf-1, minptr, voibuf[1][AF], pitch, &midx );
  212. ipitch = tau[midx-1];
  213.  
  214. /*   Place spectrum analysis and energy windows */
  215. placea( ipitch, voibuf/*-(AF+1)*/, obound[AF-1], vwin, awin, ewin);
  216.  
  217. /*   Remove short term DC bias over the analysis window, Put result in ABUF */
  218.  
  219. lanal = awin[1][AF-1] + 1 - awin[0][AF-1];
  220.  
  221. dcbias(lanal, &pebuf[awin[0][AF-1]]-1, abuf-1 );
  222.  
  223. /*   Compute RMS over integer number of pitch periods within the
  224. *   analysis window.
  225. *   Note that in a hardware implementation this computation may be
  226. *   simplified by using diagonal elements of PHI computed by MLOAD.
  227. */
  228. energy( ewin[1][AF-1]-ewin[0][AF-1]+1, &abuf[ewin[0][AF-1]-awin[0][AF-1]]-1, &rmsbuf[AF-1] );
  229.  
  230. /*   Matrix load and invert, check RC's for stability  */
  231. mload(lanal, abuf-1, phi, psi-1 );
  232. invert(phi, psi, rcbuf);
  233. rcchk(rcbuf);
  234.  
  235. /*   Set return parameters  */
  236.  
  237. voice[0] = voibuf[0][AF-2];
  238. voice[1] = voibuf[1][AF-2];
  239. *rms = rmsbuf[AF-3];
  240. for(i = 1;i<=ORDER;i++)
  241.     rc[i] = rcbuf[i-1][AF-3];
  242. }
  243.